﻿using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using Microsoft.Office.PowerPoint.STAMP.Common;
using Microsoft.Office.PowerPoint.STAMP.Controls;
using Microsoft.Office.PowerPoint.STAMP.Core;
using Microsoft.Office.PowerPoint.STAMP.Properties;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace Microsoft.Office.PowerPoint.STAMP
{
    /// <summary>
    /// Allows the user to edit the defaults for the application.
    /// </summary>
    public partial class SettingsEditor : Form
    {
        private FormattingToolbarSelection currentFormatting;
        private MediaAddedOption mediaAddedOption;

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsEditor"/> class.
        /// </summary>
        public SettingsEditor()
        {
            InitializeComponent();
            InitialiseCurrentFormatting();

            formattingToolbar.UpdateCurrentFontSelection(currentFormatting);
            fadeDurationUpDown.Value = (decimal)Settings.Default.DefaultFadeDuration;
            transparencyUpDown.Value = (decimal)(Settings.Default.DefaultTransparency * 100);
            bookmarkPrecisionUpDown.Value = Settings.Default.BookmarkPrecision;
            MediaAddedOptionsRadioButtonValue = Settings.Default.MediaAddedOption;
            mediaAddedOption = Settings.Default.MediaAddedOption;

            UpdateSampleText(currentFormatting);
            UpdateTimingExample();
            UpdateButtonEnabledStates();
        }

        private void InitialiseCurrentFormatting()
        {
            CaptionFontSize fontSize = Settings.Default.UseAutoFont ? CaptionFontSize.Auto : new CaptionFontSize(Settings.Default.DefaultFont.SizeInPoints);
            currentFormatting = new FormattingToolbarSelection(Settings.Default.DefaultFont.FontFamily,
                                                                fontSize, 
                                                                Settings.Default.DefaultAlignment,
                                                                Settings.Default.DefaultFont.Italic,
                                                                Settings.Default.DefaultFont.Bold,
                                                                Settings.Default.DefaultFont.Underline,
                                                                Settings.Default.DefaultFontColor,
                                                                Settings.Default.DefaultBackgroundColor);
        }

        private void UpdateSampleText(FormattingToolbarSelection formatting)
        {
            currentFormatting = formatting;
            sampleTextPictureBox.Refresh();
        }

        private void formattingToolbar_FontSelectionChanged(object sender, FormattingToolbarFontSelectionChangedEventArgs e)
        {
            UpdateSampleText(e.UpdatedFormattingToolbarSelection);
            UpdateButtonEnabledStates();
        }

        private void transparencyUpDown_ValueChanged(object sender, EventArgs e)
        {
            UpdateSampleText(currentFormatting);
            UpdateButtonEnabledStates();
        }

        private void sampleText_Paint(object sender, PaintEventArgs e)
        {
            Brush backgroundBrush = CreateBrush(currentFormatting.BackgroundColor ?? Settings.Default.DefaultBackgroundColor);
            Rectangle captionRectangle = CalculateDisplayRectangle();
            e.Graphics.FillRectangle(backgroundBrush,captionRectangle);
            Font textFont = new Font(currentFormatting.FontFamily, currentFormatting.FontSize.PointSize ?? 18, FontService.LoadFontStyle(currentFormatting, FontStyle.Regular));

            StringFormat stringFormat = new StringFormat
                                            {
                                                Alignment = AlignmentConverter.ConvertToStringAlignment(currentFormatting.Alignment),
                                                LineAlignment = StringAlignment.Center,
                                                Trimming = StringTrimming.None,
                                                FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.NoWrap
                                            };
            Brush fontBrush = CreateBrush(currentFormatting.FontColor ?? Settings.Default.DefaultFontColor);
            e.Graphics.DrawString("Example Text", textFont, fontBrush, captionRectangle, stringFormat);
        }

        private Rectangle CalculateDisplayRectangle()
        {
            Rectangle outerRectangle = sampleTextPictureBox.DisplayRectangle;
            int height = outerRectangle.Height / 2;
            return new Rectangle(outerRectangle.X,outerRectangle.Y + height, outerRectangle.Width, height + 1);
        }

        private Brush CreateBrush(Color baseColor)
        {
            Color backgroundColor = Color.FromArgb((int) ((100 - transparencyUpDown.Value)  * (decimal) 2.5),baseColor);
            return new SolidBrush(backgroundColor);
        }

        private void SettingsEditor_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult == DialogResult.Cancel && IsDirty)
            {
                DialogResult dialogResult = MessageBox.Show(Resources.CaptionEditor_SettingsEditor_FormClosing_UnsavedSettings,
                                                            Resources.Stamp_DiscardChanges, MessageBoxButtons.YesNo);
                e.Cancel = dialogResult == DialogResult.No;
            }
        }

        private bool IsDirty
        {
            get
            {
                return (decimal) Settings.Default.DefaultFadeDuration != fadeDurationUpDown.Value
                       || (int)(Settings.Default.DefaultTransparency*100) != transparencyUpDown.Value
                       || Settings.Default.BookmarkPrecision != bookmarkPrecisionUpDown.Value
                       || Settings.Default.DefaultFont.FontFamily.Name != currentFormatting.FontFamily.Name
                       || Settings.Default.UseAutoFont != currentFormatting.FontSize.IsAuto
                       || (Settings.Default.UseAutoFont ? false : (Settings.Default.DefaultFont.SizeInPoints != currentFormatting.FontSize.PointSize))
                       || Settings.Default.DefaultAlignment != currentFormatting.Alignment
                       || Settings.Default.DefaultFont.Bold != currentFormatting.IsBold
                       || Settings.Default.DefaultFont.Italic != currentFormatting.IsItalic
                       || Settings.Default.DefaultFont.Underline != currentFormatting.IsUnderline
                       || Settings.Default.DefaultFontColor != currentFormatting.FontColor
                       || Settings.Default.DefaultBackgroundColor != currentFormatting.BackgroundColor
                       || Settings.Default.MediaAddedOption != mediaAddedOption
                       ; 
            }
        }

        private void applyButton_Click(object sender, EventArgs e)
        {
            SaveSettings();
            UpdateButtonEnabledStates();
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            SaveSettings();
        }

        private void SaveSettings()
        {
            try
            {
                Settings.Default.DefaultFadeDuration = (float)fadeDurationUpDown.Value;
                Settings.Default.DefaultTransparency = (float)transparencyUpDown.Value / 100;
                Settings.Default.BookmarkPrecision = (int)bookmarkPrecisionUpDown.Value;
                Settings.Default.UseAutoFont = currentFormatting.FontSize.IsAuto;

                Settings.Default.DefaultFont = new Font(
                    currentFormatting.FontFamily,
                    currentFormatting.FontSize.PointSize == null ? 18 : (float)currentFormatting.FontSize.PointSize,
                    FontService.LoadFontStyle(currentFormatting, FontStyle.Regular));

                if (currentFormatting.Alignment != null)
                    Settings.Default.DefaultAlignment = (HorizontalAlignment)currentFormatting.Alignment;


                if (currentFormatting.FontColor != null)
                    Settings.Default.DefaultFontColor = currentFormatting.FontColor.Value;
                if (currentFormatting.BackgroundColor != null)
                    Settings.Default.DefaultBackgroundColor = currentFormatting.BackgroundColor.Value;
                Settings.Default.MediaAddedOption = mediaAddedOption; 

                Settings.Default.Save();
            }
            catch (Exception exception)
            {
                bool rethrow = ExceptionPolicy.HandleException(exception, "Global Policy");
                if (rethrow)
                    throw;
                DialogResult = DialogResult.Abort;
                Close();
            }
            
        }

        private void fadeDurationUpDown_ValueChanged(object sender, EventArgs e)
        {
            UpdateButtonEnabledStates();
        }

        private void UpdateButtonEnabledStates()
        {
            applyButton.Enabled = IsDirty;
        }

        private void bookmarkPrecisionUpDown_ValueChanged(object sender, EventArgs e)
        {
            UpdateTimingExample();
            UpdateButtonEnabledStates();
        }

        private void UpdateTimingExample()
        {
            timeExampleLabel.Text = new TimeSpanFormatter().Format(new TimeSpan(0, 12, 23, 34, 678),
                                                                   CultureInfo.CurrentCulture,
                                                                   (int) bookmarkPrecisionUpDown.Value);
        }

        private void mediaAddedOptionsRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            mediaAddedOption = MediaAddedOptionsRadioButtonValue;
            UpdateButtonEnabledStates();
        }

        private MediaAddedOption MediaAddedOptionsRadioButtonValue
        {
            get
            {
                if (doNothingRadioButton.Checked)
                    return MediaAddedOption.None;
                if (createCaptionsRadioButton.Checked)
                    return MediaAddedOption.CreateCaptions;
                return MediaAddedOption.ImportCaptions;
            }
            set
            {
                switch (value)
                {
                    case MediaAddedOption.None:
                        doNothingRadioButton.Checked = true;
                        break;
                    case MediaAddedOption.CreateCaptions:
                        createCaptionsRadioButton.Checked = true;
                        break;
                    case MediaAddedOption.ImportCaptions:
                        importCaptionsRadioButton.Checked = true;
                        break;
                }
            }
        }
    }
}
